﻿using Bilibili.Common.Log;
using Bilibili.Model.Comment;
using Bilibili.Model.Common;
using Bilibili.Model.Resource;
using PCLUntils.Json;
using PCLUntils.Objects;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xam.Bilibili.Lib.Extensions;

namespace Bilibili.WebClient.Api
{
    public sealed class EmoteClient : ClientBase
    {
        private static EmoteClient _Instance;
        public static EmoteClient Instance
        {
            get
            {
                _Instance ??= new EmoteClient();
                return _Instance;
            }
        }
        public DictoryEx<EmoteMode, EmotePackage> EmotePackages { get; }
        public EmoteResult EmoteResult { get; private set; } = EmoteResult.Failed;
        private EmoteClient()
        {
            EmotePackages = new DictoryEx<EmoteMode, EmotePackage>();
        }
        public async Task LoadCache()
        {
            try
            {
                int count = 0;
                var res = EmoteResult;
                if (res != EmoteResult.Success && res != EmoteResult.Dynamic)
                {
                    var model = await LoadEmote("dynamic");
                    if (model.Success && model.Data != null)
                    {
                        count++;
                        EmoteResult = EmoteResult.Dynamic;
                        EmotePackages.Remove(EmoteMode.dynamic);
                        foreach (var data in model.Data)
                        {
                            if (data.Emote == null || data.Emote.Count == 0)
                                continue;
                            EmotePackages.Add(EmoteMode.dynamic, data);
                        }
                    }
                }
                if (res != EmoteResult.Success && res != EmoteResult.Reply)
                {
                    var result = await LoadEmote("reply");
                    if (result.Success && result.Data != null)
                    {
                        count++;
                        EmoteResult = EmoteResult.Reply;
                        EmotePackages.Remove(EmoteMode.reply);
                        foreach (var data in result.Data)
                        {
                            if (data.Emote == null || data.Emote.Count == 0)
                                continue;
                            EmotePackages.Add(EmoteMode.reply, data);
                        }
                    }
                }
                if (EmotePackages.Count > 0 && count == 2)
                    EmoteResult = EmoteResult.Success;
            }
            catch (Exception ex)
            {
                LogManager.Instance.LogError("LoadCache", ex);
            }
        }
        private async Task<ReturnModel<List<EmotePackage>>> LoadEmote(string type)
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo("https://api.bilibili.com/x/emote/user/panel", $"&business={type}", true);
                var results = await ApiClient.GetResults(apiInfo);
                var obj = results.ToJObject();
                if (obj.IsNotEmpty() && obj["code"].ToInt32() == 0)
                {
                    var m = obj["data"]["packages"].ToObject<List<EmotePackage>>();
                    return BuildSuccessResult(m);
                }
                else
                {
                    var message = obj == null ? string.Empty : obj["message"].ToString();
                    return BuildFailedResult<List<EmotePackage>>(message);
                }
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<List<EmotePackage>>(ex);
            }
        }
    }
}